package org.openkanban.client.ui.board;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.openkanban.client.ui.presenter.CreateKanbanRequestCallback;
import org.openkanban.client.ui.presenter.GetKanbanUserRequestCallback;
import org.openkanban.client.ui.presenter.PreparedRequest;
import org.openkanban.client.ui.presenter.UpdateKanbanRequestCallback;
import org.openkanban.client.util.RootPanel;
import org.openkanban.client.util.StringUtils;
import org.openkanban.shared.dto.KanbanDto;
import org.openkanban.shared.dto.UserDto;

import com.google.gwt.http.client.RequestCallback;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.BkgndRepeat;
import com.smartgwt.client.types.TextAreaWrap;
import com.smartgwt.client.types.VerticalAlignment;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.TextAreaItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.Layout;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.tile.TileRecord;

/**
 * GUI Element for the KanbanEditView
 */
public class KanbanEditView extends VLayout {

    private static final int FORM_WIDTH = 450;
    private final Label moreContentLabel = null;
    private Label titleLabel;
    private HLayout footerHLayout = new HLayout();

    private Long parentActivityId;

    private TextAreaItem kanbanTitleTextItem;
    private TextAreaItem kanbanDescriptionTextItem;
    private DynamicForm kanbanForm;
    private TextItem effortTextItem;
    private KanbanContactTileGrid kanbanContactsTileGrid;
    private KanbanView kanbanView;

    public KanbanEditView() {
	setStyleName("kanban");
	setShowEdges(true);
	setBackgroundImage("corners/kanban_C.png");
	setBackgroundRepeat(BkgndRepeat.REPEAT);
	setEdgeImage("corners/kanban.png");
	setEdgeSize(15);

	setWidth(FORM_WIDTH);
	setAutoHeight();
	setCanDrag(false);
	setCanDragReposition(false);
	setShowHover(false);
	setOpacity(100);
	setAlign(VerticalAlignment.TOP);

	kanbanForm = new DynamicForm();

	kanbanTitleTextItem = new TextAreaItem();
	kanbanTitleTextItem.setName("kanbantitle");
	kanbanTitleTextItem.setWidth(FORM_WIDTH);
	kanbanTitleTextItem.setHeight(32);
	kanbanTitleTextItem.setShowTitle(false);
	kanbanTitleTextItem.setShowFocused(true);
	kanbanTitleTextItem.setTextBoxStyle("kanbanEditTitle");
	kanbanTitleTextItem.setWrap(TextAreaWrap.SOFT);
	kanbanTitleTextItem.setColSpan(2);

	kanbanDescriptionTextItem = new TextAreaItem();
	kanbanDescriptionTextItem.setName("text");
	kanbanDescriptionTextItem.setWidth(FORM_WIDTH);
	kanbanDescriptionTextItem.setHeight(104);
	kanbanDescriptionTextItem.setShowTitle(false);
	kanbanDescriptionTextItem.setShowFocused(true);
	kanbanDescriptionTextItem.setTextBoxStyle("kanbanText");
	kanbanDescriptionTextItem.setWrap(TextAreaWrap.SOFT);

	kanbanForm.setFields(kanbanTitleTextItem, kanbanDescriptionTextItem);
	kanbanForm.setWidth(FORM_WIDTH);
	kanbanForm.setAutoHeight();

	kanbanContactsTileGrid = new KanbanContactTileGrid();

	effortTextItem = new TextItem();
	effortTextItem.setName("Effort");
	effortTextItem.setShowTitle(true);
	effortTextItem.setWidth(40);

	DynamicForm effortForm = new DynamicForm();
	effortForm.setFields(effortTextItem);

	IButton saveButton = new OpenKanbanButton("save");
	saveButton.setWidth(40);
	saveButton.addClickHandler(new SaveKanbanClickHandler(this));

	IButton cancelButton = new OpenKanbanButton("close");
	cancelButton.setWidth(40);
	cancelButton.setPageLeft(5);
	cancelButton.addClickHandler(new ClickHandler() {
	    @Override
	    public void onClick(ClickEvent event) {
		RootPanel.activateEditKanbanMode(false);
	    }
	});

	VLayout bottomRightLayout = new VLayout();
	bottomRightLayout.setAlign(Alignment.RIGHT);
	bottomRightLayout.addMember(effortForm);

	HLayout bottomRightButtonLayout = new HLayout();
	bottomRightButtonLayout.setAlign(Alignment.RIGHT);
	bottomRightButtonLayout.addMember(saveButton);
	bottomRightButtonLayout.addMember(cancelButton);

	bottomRightLayout.addMember(bottomRightButtonLayout);

	HLayout bottomLayout = new HLayout();
	bottomLayout.setPadding(2);

	Layout contactsBorderLayout = new Layout();
	contactsBorderLayout.setWidth(350);
	contactsBorderLayout.setHeight(57);
	contactsBorderLayout.setBorder("1px solid #808080");
	contactsBorderLayout.addMember(kanbanContactsTileGrid);

	bottomLayout.addMember(contactsBorderLayout);
	bottomLayout.addMember(bottomRightLayout);

	addMember(kanbanForm);
	addMember(bottomLayout);
    }

    class SaveKanbanClickHandler implements ClickHandler {

	private KanbanEditView kanbanEditView;

	public SaveKanbanClickHandler(KanbanEditView kanbanEditView) {
	    this.kanbanEditView = kanbanEditView;
	}

	@Override
	public void onClick(ClickEvent event) {
	    if (kanbanEditView.getKanbanForm().validate()) {
		RequestCallback requestCallback = null;
		KanbanDto kanbanDto = null;
		String ressource = null;
		String context = null;

		if (kanbanView == null) {
		    requestCallback = new CreateKanbanRequestCallback(kanbanEditView);
		    kanbanDto = new KanbanDto();
		    context = "activity";
		    ressource = kanbanEditView.getParentActivityId().toString() + "/kanban/add";
		} else {
		    requestCallback = new UpdateKanbanRequestCallback(kanbanView);
		    kanbanDto = kanbanView.getKanbanDto();
		    context = "kanban";
		    ressource = "update";
		}

		kanbanDto.setTitle(StringUtils.toString(kanbanEditView.getKanbanTitle().getValueAsString()));
		kanbanDto.setDescription(StringUtils.toString(kanbanEditView.getKanbanText().getValueAsString()));
		kanbanDto.setEffort(StringUtils.toString(kanbanEditView.getEffort().getValueAsString()));

		Record[] contactRecords = kanbanEditView.getKanbanContacts().getData();

		if (contactRecords != null && contactRecords.length > 0) {
		    Set<Long> userIdSet = new HashSet<Long>();

		    for (int i = 0; i < contactRecords.length; i++) {
			Record contactRecord = contactRecords[i];
			Long userId = contactRecord.getAttributeAsLong("userId");
			userIdSet.add(userId);
		    }

		    kanbanDto.getKanbanUserIds().addAll(userIdSet);
		}

		PreparedRequest prepReq = new PreparedRequest(context, ressource, kanbanDto);
		prepReq.sendAsyncRequest(requestCallback);
	    }
	}
    }

    public void loadKanban(KanbanView kanbanView) {
	this.kanbanView = kanbanView;

	KanbanDto kanbanDto = kanbanView.getKanbanDto();

	kanbanTitleTextItem.setValue(kanbanDto.getTitle());
	kanbanDescriptionTextItem.setValue(kanbanDto.getDescription());
	effortTextItem.setValue(kanbanDto.getEffort());

	PreparedRequest prepReq = new PreparedRequest("kanban", kanbanDto.getKanbanId().toString() + "/user");
	prepReq.sendAsyncRequest(new GetKanbanUserRequestCallback(this));
    }

    public void showKanbanUser(List<UserDto> userResultList) {
	kanbanContactsTileGrid.setData(new TileRecord[] {});
	for (UserDto userDto : userResultList) {
	    TileRecord tr = new TileRecord();
	    tr.setAttribute("userId", userDto.getUserId());
	    tr.setAttribute("avatarUrl", userDto.getAvatarUrl());
	    tr.setAttribute("namensKuerzel", userDto.getNamensKuerzel());
	    kanbanContactsTileGrid.addData(tr);
	}
    }

    public void clear() {
	kanbanView = null;

	kanbanTitleTextItem.clearValue();
	kanbanDescriptionTextItem.clearValue();
	kanbanContactsTileGrid.selectAllRecords();
	kanbanContactsTileGrid.removeSelectedData();
	effortTextItem.clearValue();
    }

    public Label getTitleLabel() {
	return titleLabel;
    }

    public TextAreaItem getKanbanTitle() {
	return kanbanTitleTextItem;
    }

    public void setKanbanTitle(TextAreaItem kanbanTitle) {
	this.kanbanTitleTextItem = kanbanTitle;
    }

    public TextAreaItem getKanbanText() {
	return kanbanDescriptionTextItem;
    }

    public void setKanbanText(TextAreaItem kanbanText) {
	this.kanbanDescriptionTextItem = kanbanText;
    }

    public DynamicForm getKanbanForm() {
	return kanbanForm;
    }

    public void setKanbanForm(DynamicForm kanbanForm) {
	this.kanbanForm = kanbanForm;
    }

    public TextItem getEffort() {
	return effortTextItem;
    }

    public void setEffort(TextItem effort) {
	this.effortTextItem = effort;
    }

    public KanbanContactTileGrid getKanbanContacts() {
	return kanbanContactsTileGrid;
    }

    public void setKanbanContacts(KanbanContactTileGrid kanbanContacts) {
	this.kanbanContactsTileGrid = kanbanContacts;
    }

    public void setTitleLabel(Label titleLabel) {
	this.titleLabel = titleLabel;
    }

    public Label getMoreContentLabel() {
	return moreContentLabel;
    }

    public Long getParentActivityId() {
	return parentActivityId;
    }

    public void setParentActivityId(Long parentActivityId) {
	this.parentActivityId = parentActivityId;
    }

    public HLayout getFooterHLayout() {
	return footerHLayout;
    }

}
